/*
** Xin YUAN, 2024, BSD (2)
*/

////////////////////////////////////////////////////////////////////////////////
#ifndef __W_THREAD_POOL_H__
#define __W_THREAD_POOL_H__
////////////////////////////////////////////////////////////////////////////////

#define _POOL_MAX_THREAD_NUM  (500)

//_w_thread_pool_base

class _w_thread_pool_base
{
public:
	_w_thread_pool_base() noexcept : m_lExit(0), m_pGroup(NULL)
	{
	}
	_w_thread_pool_base(const _w_thread_pool_base&) = delete;
	~_w_thread_pool_base() noexcept
	{
		assert( !is_valid() );
	}

	_w_thread_pool_base& operator=(const _w_thread_pool_base&) = delete;

protected:
	bool init() noexcept
	{
		assert( !is_valid() );
		//thread pool
		::InitializeThreadpoolEnvironment(&m_cbe);
		m_pGroup = ::CreateThreadpoolCleanupGroup();
		if ( m_pGroup == NULL ) { //::GetLastError()
			::DestroyThreadpoolEnvironment(&m_cbe);
			return false;
		}
		::SetThreadpoolCallbackCleanupGroup(&m_cbe, m_pGroup, NULL);
		return true;
	}

	void dump() noexcept
	{
		if ( is_valid() ) {
			::InterlockedCompareExchange(&m_lExit, 1, 0);
			//close all
			::CloseThreadpoolCleanupGroupMembers(m_pGroup, TRUE, NULL);  //may block
			::CloseThreadpoolCleanupGroup(m_pGroup);
			m_pGroup = NULL;
			::DestroyThreadpoolEnvironment(&m_cbe);
			//restore
			::InterlockedCompareExchange(&m_lExit, 0, 1);
		}
	}

	bool is_valid() const noexcept
	{
		return m_pGroup != NULL;
	}

protected:
	volatile LONG m_lExit;

	TP_CALLBACK_ENVIRON m_cbe;

private:
	PTP_CLEANUP_GROUP m_pGroup;
};

////////////////////////////////////////////////////////////////////////////////
#endif
////////////////////////////////////////////////////////////////////////////////
